#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>

struct env_info {
    uint8_t head[3];	 //标识位st:
    uint8_t type;		 //数据类型
    uint8_t snum;		 //房间编号
    uint8_t temp[2];	 //温度	
    uint8_t hum[2];		 //湿度
    uint8_t x;			 //三轴信息
    uint8_t y;			 
    uint8_t z;			 
    uint32_t ill;		 //光照
    uint32_t bet;		 //电池电量
    uint32_t adc; 		 //电位器信息
};


#define ENV_LEN sizeof(struct env_info)
#define CONVER_ENV_LEN sizeof(struct conver_env_info)

float temperature;	 //温度	
float humidity;		 //湿度
int ill;		 //光照
    
float dota_atof (char unitl);
int dota_atoi (const char *cDecade);
float dota_adc (unsigned int ratio);

#define DEV_UART 			"/dev/ttyUSB0"

void serial_init(int fd)
{
    struct termios options;
    tcgetattr(fd, &options);
    options.c_cflag |= ( CLOCAL | CREAD );
    options.c_cflag &= ~CSIZE;
    options.c_cflag &= ~CRTSCTS;
    options.c_cflag |= CS8;
    options.c_cflag &= ~CSTOPB;
    options.c_iflag |= IGNPAR;
    options.c_iflag &= ~(ICRNL | IXON);
    options.c_oflag = 0;
    options.c_lflag = 0;

    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);
    tcsetattr(fd,TCSANOW,&options);
}


int main(int argc, char *argv[])
{
    int fd;
    int nbytes = 0;
    struct env_info envinfo;  //原始数据

    if ((fd = open(DEV_UART, O_RDWR)) < 0)
    {
        perror ("open uart err\n");
        return -1;
    }

    serial_init(fd);
	
    while (1) {
        nbytes = read(fd, &envinfo, ENV_LEN);
        if(nbytes == ENV_LEN){
        printf("raw data ill=%d, x=%d, y=%d, z=%d\n",\
            envinfo.ill, envinfo.x, envinfo.y, envinfo.z);
        }else {
            printf("err data");
        }

        temperature = envinfo.temp[0] + dota_atof(envinfo.temp[1]);
        humidity = envinfo.hum[0] + dota_atof(envinfo.hum[1]);
        ill = envinfo.ill;

        printf("conver temperature=%0.2f, humidity=%0.2f, ill=%d\n", \
               temperature, humidity, ill);
    }

    return 0;
}

float dota_atof (char unitl)
{
    if (unitl > 100)
    {
        return unitl / 1000.0;
    }
    else if (unitl > 10)
    {
        return unitl / 100.0;
    }
    else
    {
        return unitl / 10.0;
    }
}

int dota_atoi (const char *cDecade)
{
    int result = 0;
    if (' ' != cDecade[0])
    {
        result = (cDecade[0] - 48) * 10;
    }
    result += cDecade[1] - 48;
    return result;
}

float dota_adc (unsigned int ratio)
{
    return ((ratio * 3.3) / 1024);
}
